﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace ConfigReader
{
    public class InitData
    {
        public Vector3 Pos;
        public Vector3 Rot;
    }

    public class Physics
    {
        public enum PType { HAIR, CLOTH, BREAST }
        public PType Type;
        public String ID;
        public float Mass;
        public List<String> Bones;
    }

    public class CAnimation
    {
        private String name;
        private float? scale;
        private int? repeat;
        private int? next;

        public String Name
        {
            get { return name; }
            set { name = value; }
        }

        [ContentSerializer(Optional = true)]
        public float? Scale
        {
            get { return scale; }
            set { scale = value; }
        }

        [ContentSerializer(Optional = true)]
        public int? Repeat
        {
            get { return repeat; }
            set { repeat = value; }
        }

        [ContentSerializer(Optional = true)]
        public int? Next
        {
            get { return next; }
            set { next = value; }
        }
    }

    public class Imports
    {
        private List<String> morphs;
        private List<CAnimation> skeletal;
        private List<String> visemes;
        private List<int> visemeMap;
        private List<String> knowledgeBase;

        [ContentSerializer(Optional = true)]
        public List<String> Morphs
        {
            get { return morphs; }
            set { morphs = value; }
        }
        [ContentSerializer(Optional = true)]
        public List<CAnimation> Skeletal
        {
            get { return skeletal; }
            set { skeletal = value; }
        }
        [ContentSerializer(Optional = true)]
        public List<String> Visemes
        {
            get { return visemes; }
            set { visemes = value; }
        }
        [ContentSerializer(Optional = true)]
        public List<int> VisemeMap
        {
            get { return visemeMap; }
            set { visemeMap = value; }
        }
        [ContentSerializer(Optional = true)]
        public List<String> KnowledgeBase
        {
            get { return knowledgeBase; }
            set { knowledgeBase = value; }
        }
    }

    public class ConfigXML
    {
        public enum MType { SKINNED, STATIC }
        private String cID;
        private String cName;
        private MType cType;
        private Boolean noLoad;
        private Int16? cDrawOrder;
        private String cParent;
        private String cAttachTo;
        private List<String> cNotVisible;
        private InitData cInitData;
        private List<CAnimation> cAnimation;
        private String cDefAnimation;
        private List<Physics> cPhysics;
        private Imports cImports;

        #region Get/Set Methods
        public String ID
        {
            get { return cID; }
            set { cID = value; }
        }

        public String Name
        {
            get { return cName; }
            set { cName = value; }
        }


        public MType Type
        {
            get { return cType; }
            set { cType = value; }
        }

        [ContentSerializer(Optional = true)]
        public Boolean NoLoad
        {
            get { return noLoad; }
            set { noLoad = value; }
        }

        [ContentSerializer(Optional = true)]
        public Int16? DrawOrder
        {
            get { return cDrawOrder; }
            set { cDrawOrder = value; }
        }

        [ContentSerializer(Optional = true)]
        public String Parent
        {
            get { return cParent; }
            set { cParent = value; }
        }

        [ContentSerializer(Optional = true)]
        public String AttachTo
        {
            get { return cAttachTo; }
            set { cAttachTo = value; }
        }

        [ContentSerializer(Optional = true)]
        public List<String> NotVisible
        {
            get { return cNotVisible; }
            set { cNotVisible = value; }
        }

        [ContentSerializer(Optional = true)]
        public InitData InitialData
        {
            get { return cInitData; }
            set { cInitData = value; }
        }

        [ContentSerializer(Optional = true)]
        public List<CAnimation> Animation
        {
            get { return cAnimation; }
            set { cAnimation = value; }
        }

        [ContentSerializer(Optional = true)]
        public String DefAnimation
        {
            get { return cDefAnimation; }
            set { cDefAnimation = value; }
        }

        [ContentSerializer(Optional = true)]
        public List<Physics> Physics
        {
            get { return cPhysics; }
            set { cPhysics = value; }
        }

        [ContentSerializer(Optional = true)]
        public Imports Import
        {
            get { return cImports; }
            set { cImports = value; }
        }

        #endregion

        #region Content Type Reader
        public class ConfigXMLReader : ContentTypeReader<ConfigXML>
        {
            protected override ConfigXML Read(ContentReader input,
                ConfigXML existingInstance)
            {
                ConfigXML configXML = existingInstance;
                if (configXML == null)
                {
                    configXML = new ConfigXML();
                }

                configXML.ID = input.ReadString();
                configXML.Name = input.ReadString();               
                configXML.Type = input.ReadObject<MType>();
                configXML.NoLoad = input.ReadBoolean();
                configXML.DrawOrder = input.ReadInt16();
                configXML.Parent = input.ReadString();
                configXML.AttachTo = input.ReadString();
                configXML.NotVisible.AddRange(input.ReadObject<List<String>>());
                configXML.InitialData = input.ReadObject<InitData>();
                configXML.Animation.AddRange(input.ReadObject<List<CAnimation>>());
                configXML.DefAnimation = input.ReadString();
                configXML.Physics.AddRange(input.ReadObject<List<Physics>>());
                configXML.Import = input.ReadObject<Imports>();

                return configXML;
            }
        }

        #endregion

    }
}
